package com.yuwen.yuwenRPC.loadbalancer;

/**
 * @ClassNameConsistentHashLoadBalancer
 * @Description TODO
 * @Author钰玟
 * @Date2025/4/5 下午8:24
 * @Version 1.0
 **/


import com.yuwen.yuwenRPC.model.ServiceMetaInfo;

import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * 一致性 Hash 负载均衡器
 */
public class ConsistentHashLoadBalancer implements LoadBalancer {

    /**
     * 一致性Hash环 存放虚拟节点数
     */
    private final TreeMap<Integer,ServiceMetaInfo> virtualNodes = new TreeMap<>();


    /**
     * 虚拟节点的个数
     */
    private final int  VIRTUAL_NODE_NUM = 100;


    /**
     * Hash一致性 负载均衡器
     * @param requestParams 请求参数
     * @param servicesMetaInfoList 可用的服务列表
     * @return hash
     */
    @Override
    public ServiceMetaInfo select(Map<String, Object> requestParams, List<ServiceMetaInfo> servicesMetaInfoList) {
        if(servicesMetaInfoList.isEmpty()){
            return null;
        }
        //构建哈希虚拟环
        for (ServiceMetaInfo serviceMetaInfo : servicesMetaInfoList) {
            for (int i = 0; i < VIRTUAL_NODE_NUM; i++) {
                //生成hash值
                int hash = getHash(serviceMetaInfo.getServiceAddress()+"#"+i);
                //放入虚拟环
                virtualNodes.put(hash, serviceMetaInfo);
            }
        }

        int hash = getHash(requestParams);
        //选择大于等于 hash值的虚拟节点
        Map.Entry<Integer, ServiceMetaInfo> entry = virtualNodes.ceilingEntry(hash);
        if(entry == null){
            //没有，则返回虚拟环首部节点
            entry = virtualNodes.firstEntry();
        }
        return entry.getValue();

    }


    private int getHash(Object key) {
        return key.hashCode();
    }
}
